package com.weatherstation.service;

import com.weatherstation.entity.SensorData;
import com.weatherstation.mapper.SensorDataMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.Map;
import java.util.HashMap;

/**
 * 传感器数据服务类
 * 
 * @author WeatherStation Team
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SensorDataService {
    
    private final SensorDataMapper sensorDataMapper;
    
    /**
     * 保存传感器数据
     */
    @Transactional
    public SensorData saveSensorData(SensorData sensorData) {
        try {
            sensorDataMapper.insert(sensorData);
            log.info("保存传感器数据成功: {}", sensorData.getId());
            return sensorData;
        } catch (Exception e) {
            log.error("保存传感器数据失败", e);
            throw new RuntimeException("保存传感器数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 批量保存传感器数据
     */
    @Transactional
    public List<SensorData> saveBatchSensorData(List<SensorData> sensorDataList) {
        try {
            for (SensorData sensorData : sensorDataList) {
                sensorDataMapper.insert(sensorData);
            }
            log.info("批量保存传感器数据成功，数量: {}", sensorDataList.size());
            return sensorDataList;
        } catch (Exception e) {
            log.error("批量保存传感器数据失败", e);
            throw new RuntimeException("批量保存传感器数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取最新的传感器数据
     */
    public Optional<SensorData> getLatestSensorData() {
        SensorData data = sensorDataMapper.findTopByOrderByCreatedAtDesc();
        return Optional.ofNullable(data);
    }
    
    /**
     * 获取指定时间范围内的传感器数据
     */
    public List<SensorData> getSensorDataByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        return sensorDataMapper.findByCreatedAtBetweenOrderByCreatedAtDesc(startTime, endTime);
    }
    
    /**
     * 获取最近N小时的数据
     */
    public List<SensorData> getRecentHoursData(int hours) {
        LocalDateTime startTime = LocalDateTime.now().minusHours(hours);
        return sensorDataMapper.findRecentData(startTime);
    }
    
    /**
     * 获取最近N天的数据
     */
    public List<SensorData> getRecentDaysData(int days) {
        LocalDateTime startTime = LocalDateTime.now().minusDays(days);
        return sensorDataMapper.findRecentData(startTime);
    }
    
    /**
     * 获取最近10条数据
     */
    public List<SensorData> getLatest10Data() {
        return sensorDataMapper.findTop10ByOrderByCreatedAtDesc();
    }
    
    /**
     * 获取每小时平均数据
     */
    public List<Map<String, Object>> getHourlyAverageData(int hours) {
        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime startTime = endTime.minusHours(hours);

        return sensorDataMapper.findHourlyAverageData(startTime, endTime);
    }
    
    /**
     * 获取每日统计数据
     */
    public List<Map<String, Object>> getDailyStatistics(int days) {
        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime startTime = endTime.minusDays(days);

        return sensorDataMapper.findDailyStatistics(startTime, endTime);
    }
    
    /**
     * 获取数据统计信息
     */
    public Map<String, Object> getDataStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 总数据量
        Long totalCount = sensorDataMapper.getTotalCount();
        statistics.put("totalCount", totalCount);
        
        // 最新数据
        Optional<SensorData> latestData = getLatestSensorData();
        statistics.put("latestData", latestData.orElse(null));
        
        // 今日数据量
        LocalDateTime todayStart = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
        LocalDateTime todayEnd = LocalDateTime.now();
        List<SensorData> todayData = getSensorDataByTimeRange(todayStart, todayEnd);
        statistics.put("todayCount", todayData.size());
        
        // 最近24小时数据趋势
        List<SensorData> last24Hours = getRecentHoursData(24);
        statistics.put("last24HoursCount", last24Hours.size());
        
        return statistics;
    }
    
    /**
     * 清理过期数据
     */
    @Transactional
    public void cleanupOldData(int retentionDays) {
        LocalDateTime cutoffTime = LocalDateTime.now().minusDays(retentionDays);
        try {
            sensorDataMapper.deleteByCreatedAtBefore(cutoffTime);
            log.info("清理{}天前的数据完成", retentionDays);
        } catch (Exception e) {
            log.error("清理过期数据失败", e);
            throw new RuntimeException("清理过期数据失败: " + e.getMessage());
        }
    }
    

    // 转换方法已删除，因为现在查询直接返回Map
    
    /**
     * 创建传感器数据
     */
    public SensorData createSensorData(BigDecimal temperature, BigDecimal humidity, 
                                      BigDecimal pressure, Integer lightIntensity) {
        SensorData sensorData = new SensorData(temperature, humidity, pressure, lightIntensity);
        return saveSensorData(sensorData);
    }
    /**
     * 获取最近N小时的数据（带分页）
     */
    public List<SensorData> getRecentHoursDataPaged(int hours, int page, int size) {
        LocalDateTime startTime = LocalDateTime.now().minusHours(hours);
        int offset = page * size;
        return sensorDataMapper.findRecentDataPaged(startTime, size, offset);
    }
    
    /**
     * 获取数据总数（指定时间范围内）
     */
    public long getDataCountInTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        return sensorDataMapper.countByTimeRange(startTime, endTime);
    }
    
    /**
     * 获取每月统计数据
     */
    public List<Map<String, Object>> getMonthlyStatistics(int months) {
        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime startTime = endTime.minusMonths(months);
        
        return sensorDataMapper.findMonthlyStatistics(startTime, endTime);
    }
    
    // 月统计数据转换方法已删除，因为现在查询直接返回Map
    
    /**
     * 获取数据总数
     */
    public Long getTotalCount() {
        return sensorDataMapper.getTotalCount();
    }
    
    /**
     * 获取每小时数据（直接返回Map，避免Object[]转换问题）
     */
    public List<Map<String, Object>> getHourlyData(int hours) {
        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime startTime = endTime.minusHours(hours);
        
        return sensorDataMapper.findHourlyData(startTime, endTime);
    }
}